#include "semantic.h"
void SemanticAnalyzer::analyze(unique_ptr<ASTNode>& root) {
    if (auto compUnit = dynamic_cast<CompUnitNode*>(root.get())) {
        analyzeCompUnit(compUnit);
    }
}

void SemanticAnalyzer::analyzeCompUnit(CompUnitNode* node) {
    for (auto& func : node->funcs) {
        if (auto funcDef = dynamic_cast<FuncDefNode*>(func.get())) {
            analyzeFuncDef(funcDef);
        }
    }
}

void SemanticAnalyzer::analyzeFuncDef(FuncDefNode* node) {
    // 声明函数
    vector<string> paramTypes;
    for (auto& param : node->params) {
        (void)param; // 显式忽略未使用变量
        paramTypes.push_back("int"); // ToyC 目前只支持int参数
    }

    if (!declareSymbol(node->name, SymbolType::FUNCTION, node->retType, paramTypes)) {
        return;
    }

    // 进入函数作用域
    enterScope();

    // 声明参数
    for (auto& param : node->params) {
        if (auto expr = dynamic_cast<ExprNode*>(param.get())) {
            if (expr->op == "Param" && !expr->children.empty()) {
                if (auto ident = dynamic_cast<ExprNode*>(expr->children[0].get())) {
                    string paramName = ident->op;
                    declareSymbol(paramName, SymbolType::PARAMETER, "int");
                }
            }
        }
    }

    // 分析函数体
    analyzeBlock(dynamic_cast<StmtNode*>(node->body.get()), node->retType);

    // 退出函数作用域
    exitScope();
}

void SemanticAnalyzer::analyzeBlock(StmtNode* node, const string& currentReturnType) {
    enterScope(); // 进入块作用域

    for (auto& child : node->children) {
        analyzeNode(*this, child.get(), currentReturnType);
    }

    exitScope(); // 退出块作用域
}

void SemanticAnalyzer::analyzeStmt(StmtNode* node, const string& currentReturnType) {
    if (node->type == "Block") {
        analyzeBlock(node, currentReturnType);
        return;
    }

    if (node->type == "IfStmt" || node->type == "WhileStmt") {
        // 条件表达式必须是布尔类型
        if (!node->children.empty()) {
            analyzeExpr(dynamic_cast<ExprNode*>(node->children[0].get()));
        }

        // 分析语句体
        if (node->children.size() > 1) {
            analyzeNode(*this, node->children[1].get(), currentReturnType);
        }

        // 分析else部分
        if (node->children.size() > 2) {
            analyzeNode(*this, node->children[2].get(), currentReturnType);
        }
        return;
    }

    if (node->type == "ReturnStmt") {
        if (!node->children.empty()) {
            // 有返回值
            analyzeExpr(dynamic_cast<ExprNode*>(node->children[0].get()));
            if (currentReturnType == "void") {
                error("Void function cannot return a value");
            }
        }
        else if (currentReturnType != "void") {
            error("Non-void function must return a value");
        }
        return;
    }

    if (node->type == "DeclareStmt") {
        if (!node->children.empty()) {
            // 修复：正确获取变量名
            if (auto ident = dynamic_cast<ExprNode*>(node->children[0].get())) {
                string varName = ident->op;
                if (!declareSymbol(varName, SymbolType::VARIABLE, "int")) {
                    error("Redeclaration of variable '" + varName + "'");
                }
            }

            // 分析初始化表达式
            if (node->children.size() > 1) {
                analyzeExpr(dynamic_cast<ExprNode*>(node->children[1].get()));
            }
        }
        return;
    }

    if (node->type == "AssignStmt") {
        if (node->children.size() >= 2) {
            string varName = dynamic_cast<ExprNode*>(node->children[0].get())->op;
            if (!lookupSymbol(varName)) {
                error("Undeclared variable '" + varName + "'");
            }
            analyzeExpr(dynamic_cast<ExprNode*>(node->children[1].get()));
        }
        return;
    }

    if (node->type == "ExprStmt") {
        if (!node->children.empty()) {
            analyzeExpr(dynamic_cast<ExprNode*>(node->children[0].get()));
        }
    }
}

void SemanticAnalyzer::analyzeExpr(ExprNode* node) {

   // 处理数字字面量 - 只需检查类型
    (void)dynamic_cast<NumberNode*>(node); // 显式忽略结果

    if (node->op == "Primary") {
        if (!node->children.empty()) {
            if (auto child = dynamic_cast<ExprNode*>(node->children[0].get())) {
                // 标识符或函数调用
                if (child->children.empty()) {
                    string name = child->op;
                    if (!lookupSymbol(name)) {
                        error("Undeclared identifier '" + name + "'");
                    }

                    // 检查函数调用
                    if (node->children.size() > 1) {
                        auto funcSymbol = lookupSymbol(name);
                        if (!funcSymbol || funcSymbol->type != SymbolType::FUNCTION) {
                            error("'" + name + "' is not a function");
                        }
                        else {
                            // 检查参数个数
                            size_t expected = funcSymbol->paramTypes.size();
                            size_t actual = node->children.size() - 1; // 减去函数名

                            if (expected != actual) {
                                error("Function '" + name + "' expects " +
                                    to_string(expected) + " arguments but got " +
                                    to_string(actual));
                            }

                            // 分析参数表达式
                            for (size_t i = 1; i < node->children.size(); i++) {
                                analyzeExpr(dynamic_cast<ExprNode*>(node->children[i].get()));
                            }
                        }
                    }
                }
            }
        }
        return;
    }

    // 检查运算符操作数
    if (isArithmeticOp(node->op)) {
        if (node->children.size() != 2) {
            error("Arithmetic operator requires two operands");
            return;
        }
        analyzeExpr(dynamic_cast<ExprNode*>(node->children[0].get()));
        analyzeExpr(dynamic_cast<ExprNode*>(node->children[1].get()));
        return;
    }

    if (isComparisonOp(node->op) || isLogicalOp(node->op)) {
        if (node->children.size() != 2) {
            error("Comparison operator requires two operands");
            return;
        }
        analyzeExpr(dynamic_cast<ExprNode*>(node->children[0].get()));
        analyzeExpr(dynamic_cast<ExprNode*>(node->children[1].get()));
        return;
    }

    if (node->op == "!" && node->children.size() == 1) {
        analyzeExpr(dynamic_cast<ExprNode*>(node->children[0].get()));
        return;
    }

    // 递归分析子表达式
    for (auto& child : node->children) {
        analyzeExpr(dynamic_cast<ExprNode*>(child.get()));
    }
}

bool SemanticAnalyzer::isBoolOp(const string& op) {
    return op == "&&" || op == "||" || op == "!" ||
        op == "<" || op == ">" || op == "<=" ||
        op == ">=" || op == "==" || op == "!=";
}

bool SemanticAnalyzer::isArithmeticOp(const string& op) {
    return op == "+" || op == "-" || op == "*" ||
        op == "/" || op == "%";
}

bool SemanticAnalyzer::isComparisonOp(const string& op) {
    return op == "<" || op == ">" || op == "<=" ||
        op == ">=" || op == "==" || op == "!=";
}

bool SemanticAnalyzer::isLogicalOp(const string& op) {
    return op == "&&" || op == "||";
}

// 访问者模式适配实现
void analyzeNode(SemanticAnalyzer& analyzer, ASTNode* node, const string& currentReturnType) {
    if (auto exprNode = dynamic_cast<ExprNode*>(node)) {
        analyzer.analyzeExpr(exprNode);
    }
    else if (auto stmtNode = dynamic_cast<StmtNode*>(node)) {
        analyzer.analyzeStmt(stmtNode, currentReturnType);
    }
    else if (auto funcDefNode = dynamic_cast<FuncDefNode*>(node)) {
        analyzer.analyzeFuncDef(funcDefNode);
    }
    else if (auto compUnitNode = dynamic_cast<CompUnitNode*>(node)) {
        analyzer.analyzeCompUnit(compUnitNode);
    }
}